home *** CD-ROM | disk | FTP | other *** search
Wrap
<?xml version="1.0"?> <!DOCTYPE overlay SYSTEM "chrome://ybookmarks/locale/ybookmarks.dtd"> <bindings xmlns="http://www.mozilla.org/xbl" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:rdf="http://home.netscape.com/NC-rdf#" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:xbl="http://www.mozilla.org/xbl"> <binding id="ybsidebar"> <resources> <stylesheet src="chrome://ybookmarks/skin/overlay.css" /> <script src="chrome://ybookmarks/content/providerApis.js" type="application/x-javascript" /> <script src="chrome://ybookmarks/content/ybookmarksUtils.js" type="application/x-javascript" /> </resources> <implementation implements="nsIObserver, nsIRDFObserver"> <constructor> <![CDATA[ ybookmarksUtils.importSymbols(this, "gRdfService", "gRdfContainerUtils", "addObserver", "removeObserver", "nsIRDFLiteral", "bookmarkResource", "grscTag", "grscTagValue", "grscChildCount", "grscTagRoot", "grscBookmarksRoot", "grscName", "grscDesc", "grscShortcut", "grscShared", "grscType", "grscBookmarkType", "grscLivemarkType", "grscUrl", "grscVisitCount", "grscLastVisitDate", "grscAddDate", "grscIcon"); const nsIRDFLiteral = Components.interfaces.nsIRDFLiteral; const nsIRDFDate = Components.interfaces.nsIRDFDate; const nsIRDFInt = Components.interfaces.nsIRDFInt; var bookmarksStore = this.bookmarksStore; var bookmarksDatasource = this.bookmarksDatasource; var searchDatasource = this.searchDatasource; var tagsTree = this.tagsTree = this.getElementByAnonid("ybbookmarks-tree-tags"); var bookmarksTree = this.bookmarksTree = this.getElementByAnonid("ybbookmarks-tree-bookmarks"); var tagsSortMenu = this.tagsSortMenu = this.getElementByAnonid("ybsidebar-tags-sort-menu"); var tagsCount = this.tagsCount = this.getElementByAnonid("ybsidebar-tags-count"); var bookmarksSortMenu = this.bookmarksSortMenu = this.getElementByAnonid("ybsidebar-bookmarks-sort-menu"); var bookmarksCount = this.bookmarksCount = this.getElementByAnonid("ybsidebar-bookmarks-count"); var enumeratorMap = ybookmarksUtils.enumeratorMap; // import function into scope yDebug.print("$Name: del2alpha $; $Id: //DeliciousXT/Main/FFXT/del2alpha/content/ybSidebarOverlay.xml#7 $"); const theXBL = this; /****************************************************************************** Tag object ******************************************************************************/ function Tag(name, parent, isDirty) { this.Name = name; this.parent = parent; this.Level = parent ? parent.Level + 1 : 0; this.isDirty = isDirty ? isDirty : false; } Tag.prototype.memoizeGetter = ybookmarksUtils.memoizeGetter; Tag.getNameFromResource = function(tagResource) { return ybookmarksUtils.getValue(bookmarksDataSource, tagResource, grscTagValue, nsIRDFLiteral); }; Tag.getAll = function Tag__getAll() { var tagsEnumerator = gRdfContainerUtils.MakeSeq(bookmarksDataSource, grscTagRoot).GetElements(); return enumeratorMap(tagsEnumerator, function(tagResource) { var tagName = Tag.getNameFromResource(tagResource); if (bookmarksStore.getTotalBookmarksForTag(tagName) > 0) { return new Tag(tagName); } }); } Tag.prototype.getAncestors = function() { var result = []; for (var tag = this; tag != null; tag = tag.parent) { result[result.length] = tag; } return result; } Tag.prototype.getRelatedTags = function() { var tagsSet = {}, relatedTags = [], tagName = this.Name; this.bookmarks.forEach(function(bookmark) { bookmark.tags.forEach( function(tag) { tagsSet[tag.toLowerCase()] = true; } ); }); for (var k in tagsSet) { if (tagsSet.hasOwnProperty(k) && k != tagName) { relatedTags[relatedTags.length] = new Tag(k, this); } } return relatedTags; } Tag.prototype.matchesSearchQuery = function(searchQuery) { var keywords; if (searchQuery.indexOf('+') != -1) return false; keywords = searchQuery.split(' '); return ybookmarksUtils.searchStringForKeywords(this.Name, keywords); }; Tag.prototype.memoizeGetter("NumBookmarks", function() { return this.Level ? getBookmarksForTags(this.getAncestors()).length : bookmarksStore.getTotalBookmarksForTag(this.Name); }); Tag.prototype.memoizeGetter("bookmarks", function() { try { var tagLiteral = gRdfService.GetLiteral(this.Name); var tagResource = bookmarksDataSource.GetSource(grscTagValue, tagLiteral, true); var bookmarksEnumerator = gRdfContainerUtils.MakeSeq(bookmarksDataSource, tagResource).GetElements(); return enumeratorMap(bookmarksEnumerator, Bookmark.getNew); } catch (e) { yDebug.print("Tag.bookmarks getter: Failed to get bookmarks for tag: " + this.Name); return []; } }); /****************************************************************************** Bookmark object ******************************************************************************/ function Bookmark(resource, parent, isDirty) { this.resource = resource; this.parent = parent; this.Level = parent ? parent.Level + 1 : 0; this.isDirty = isDirty ? isDirty : false; } Bookmark.prototype.getValue = function(pred, iface) { var val = bookmarksDataSource.GetTarget(this.resource, pred, true); return val ? val.QueryInterface(iface).Value : 0; } Bookmark.prototype.memoizeGetter = ybookmarksUtils.memoizeGetter; Bookmark.getAll = function() { var bookmarksRoot = gRdfContainerUtils.MakeSeq(bookmarksDataSource, grscBookmarksRoot).GetElements(); return enumeratorMap(bookmarksRoot, Bookmark.getNew); } Bookmark.prototype.memoizeGetter("Name", function() { return this.getValue(grscName, nsIRDFLiteral); }); Bookmark.prototype.memoizeGetter("url", function() { return this.getValue(grscUrl, nsIRDFLiteral); }); Bookmark.prototype.memoizeGetter("shortcut", function() { return this.getValue(grscShortcut, nsIRDFLiteral) || ""; }); Bookmark.prototype.memoizeGetter("icon", function() { return this.getValue(grscIcon, nsIRDFLiteral); }); Bookmark.prototype.memoizeGetter("desc", function() { return this.getValue(grscDesc, nsIRDFLiteral); }); Bookmark.prototype.memoizeGetter("shared", function() { return "true" === this.getValue(grscShared, nsIRDFLiteral); }); Bookmark.prototype.memoizeGetter("last_visited", function() { return this.getValue(grscLastVisitDate, nsIRDFDate) / 1000000 || this.added_date; }); Bookmark.prototype.memoizeGetter("added_date", function() { return this.getValue(grscAddDate, nsIRDFDate) / 1000000 || 0; }); Bookmark.prototype.memoizeGetter("visit_count", function() { return this.getValue(grscVisitCount, nsIRDFInt); }); Bookmark.prototype.memoizeGetter("tags", function() { var tagsEnumerator = bookmarksDataSource.GetTargets(this.resource, grscTag, true); return enumeratorMap(tagsEnumerator, function(tagResource) { return tagResource.QueryInterface(nsIRDFLiteral).Value.toLowerCase() }); } ); Bookmark.prototype.isLivemark = function() { return "Livemark" === bookmarksStore.resolveBookmarkResourceType(this.resource); }, Bookmark.prototype.getLivemarkChildren = function() { if (this.isLivemark()) { var livemarkContainer = gRdfContainerUtils.MakeSeq(bookmarksDataSource, this.resource); var theBookmark = this; return enumeratorMap(livemarkContainer.GetElements(), function(feedItem) { return new Bookmark(feedItem, theBookmark); }); } else { return []; } }, Bookmark.prototype.hasTags = function(tagArray) { var tags = this.tags; for (var i = tagArray.length - 1; i >= 0; i--) { if (tags.indexOf(tagArray[i].Name) < 0) { return false; } } return true; } Bookmark.prototype.matchesSearchQuery = function(searchQuery) { var tags = this.tags; var tagCloud = ""; var conjunction = true; var keywords = searchQuery.split('+'); if (keywords.length === 1) { keywords = searchQuery.split(' '); conjuction = false; } for (var i=0; i<tags.length; i++) { tagCloud += tags[i] + " "; } return ybookmarksUtils.searchStringForKeywords(tagCloud, keywords, conjunction) || ybookmarksUtils.searchStringForKeywords(this.Name, keywords, conjunction) || ybookmarksUtils.searchStringForKeywords(this.url, keywords, conjunction) || ybookmarksUtils.searchStringForKeywords(this.desc, keywords, conjunction) || ybookmarksUtils.searchStringForKeywords(this.shortcut, keywords, conjunction); }; /* * These functions wrap the constructor so that it can be used in an Array.map call */ Tag.getNew = function(arg) { return new Tag(arg); } Bookmark.getNew = function(arg) { return new Bookmark(arg); } /** ** Get an array of bookmarks that have ALL of the tags in aTagArray ** ** @param aTagArray an array of strings representing tag names **/ function getBookmarksForTags(aTagArray) { var head = aTagArray[0]; if (!aTagArray || !aTagArray.length) { return Bookmark.getAll(); } else if (aTagArray.length == 1) { return head.bookmarks; } else { /** ** Recursive calculation of intersection; tip of the hat to Lisp :-) **/ var bookmarks_car = head.bookmarks; var bookmarks_cdr = getBookmarksForTags(aTagArray.slice(1)); var i, j, results = []; outerLoop: for (i = bookmarks_car.length - 1; i >= 0; i--) { var bookmark = bookmarks_car[i]; var resource1 = bookmark.resource; innerLoop: for (j = bookmarks_cdr.length - 1; j >= 0; j--) { if (bookmarks_cdr[j].resource == resource1) { results[results.length] = bookmark; continue outerLoop; } } } /*---------------------------------------------------- Hmmm, using the Array.filter and Array.some functions seems to be SLOWER than rolling my own loops. :-) var results = bookmarks_car.filter ( function(x) { var x_resource = x.resource; return bookmarks_cdr.some( function(y) { return y.resource == x_resource; } ); } ); --------------------------------------------------*/ return results; } } function getComparatorFunc(property) { switch (property) { case "Name": return function nameComparator(n1, n2) { var name1 = n1.Name.toLowerCase(), name2 = n2.Name.toLowerCase(); return (name1 < name2) ? -1 : (name1 > name2) ? 1 : getComparatorFunc("url")(n1, n2); }; case "url": return function urlComparator(n1, n2) { var url1 = n1.url, url2 = n2.url; return (url1 < url2) ? -1 : (url1 > url2) ? 1 : 0; }; case "resourceUri": return function resourceComparator(n1, n2) { var uri1 = n1.resource.Value, uri2 = n2.resource.Value; return (uri1 < uri2) ? -1 : (uri1 > uri2) ? 1 : 0; }; case "NumBookmarks": return function numBookmarksComparator(n1, n2) { var numBooks_diff = n2.NumBookmarks - n1.NumBookmarks; return numBooks_diff != 0 ? numBooks_diff : getComparatorFunc("Name")(n1, n2); }; case "last_visited": return function lastVisitedComparator(n1, n2) { return n2.last_visited - n1.last_visited; }; case "added_date": return function addedDateComparator(n1, n2) { return n2.added_date - n1.added_date; }; case "visit_count": return function visitCountComparator(n1, n2) { var visit_count_diff = n2.visit_count - n1.visit_count; return visit_count_diff != 0 ? visit_count_diff : getComparatorFunc("Name")(n1, n2); }; default: return null; } } /****************************************************************************** CustomTreeView ******************************************************************************/ function CustomTreeView(props) { this.addProperties(props); this.table = []; this.__defineGetter__("rowCount", function() { return this.table.length; }); } var methods = { addProperties : function(props) { for (var p in props) this[p] = props[p]; }, setData : function(data) { this.data = data; this.loadTable(); }, updateCount : function() { this.countElem.value = this.rowCount; }, setTree : function(treebox) { if (treebox && treebox !== this.treebox) { // This check prevents loads from happening on exit this.treebox = treebox; this.loadTable(); if (this.initFunction) this.initFunction(); } }, listenForEvent : function(elem, eventName, handlerFunc) { var self = this; eventHandler = function() { return self[handlerFunc](); }; return elem.addEventListener(eventName, eventHandler, true); }, hasNextSibling : function(row, afterIndex) { // Note: Called on Windows; not Mac var thisLevel = this.getLevel(row); var rowCount = this.rowCount; for (var t = afterIndex + 1; t < rowCount; t++) { var nextLevel = this.getLevel(t); if (nextLevel == thisLevel) return true; else if (nextLevel < thisLevel) return false; } return false; }, getNumChildren : function(row) { var row2 = row + 1, rowCount = this.rowCount, level = this.getLevel(row); while (row2 < rowCount && this.getLevel(row2) > level) { ++row2; } return row2 - row - 1; }, linearSearch : function(fn) { return ybookmarksUtils.linearSearch(this.table, fn); }, getRowByName : function(name) { return this.linearSearch(function(x) { return x.Name == name; }); }, getRowByResourceUri : function(resourceUri) { return this.linearSearch(function(x) { return x.resource.Value == resourceUri; }); }, invalidateRow : function(row) { this.treebox.invalidateRow(row); }, addNodes : function(row, nodes) { this.table = ybookmarksUtils.arraySplice(this.table, row, nodes); this.treebox.rowCountChanged(row, +nodes.length); }, addNode : function(row, node) { this.table.splice(row, 0, node); this.treebox.rowCountChanged(row, +1); }, deleteNodes : function(row, count) { this.table.splice(row, count); this.treebox.rowCountChanged(row, -count); }, deleteNode : function(row) { this.table.splice(row, 1); this.treebox.rowCountChanged(row, -1); }, closeNode : function(row) { this.deleteNodes(row + 1, this.getNumChildren(row)); this.table[row].isOpen = false; }, openNode : function(row) { var node = this.table[row]; var childrenToInsert = this.data.getNodes(node, this.getComparator()).map(function(x) { x.parentIndex = row; return x; }); this.addNodes(row + 1, childrenToInsert); this.table[row].isOpen = true; }, toggleOpenState : function(row) { if (this.getLevel(row) > 0) return; if (this.isContainerOpen(row)) { this.closeNode(row); } else { this.openNode(row); } this.treebox.invalidateRow(row); }, closeOpenedNodes : function() { var openedNodes = []; for (var i = this.rowCount - 1; i >= 0; i--) { if (this.table[i].isOpen) { openedNodes[openedNodes.length] = this.table[i]; this.closeNode(i); } } return openedNodes; }, openNodes : function(nodes) { for (var i = nodes.length - 1; i >= 0; i--) { var row = this.getRowByName(nodes[i].Name); if (row >= 0) { this.openNode(row); } } }, loadTable : function() { var oldRowCount = this.rowCount; this.table = this.data.getNodes(); this.treebox.rowCountChanged(0, this.rowCount - oldRowCount); this.treebox.invalidate(); this.updateCount(); return this; }, getSelectedNode : function() { var selectedIndex = this.selection ? this.selection.currentIndex : -1; return selectedIndex >= 0 ? this.table[selectedIndex] : null; }, nodeMatches : function(aPrimaryNode, aSecondaryNode) { if (aPrimaryNode.Name !== aSecondaryNode.Name) { return false; } else if (aPrimaryNode.parent && aPrimaryNode.parent !== aSecondaryNode.parent) { return false; } else { return true; } }, nodeFiltered : function(node) { return this.data.containsNode && !this.data.containsNode(node); }, clearSelection : function() { this.selection.clearSelection(); this.selection.currentIndex = -1; }, selectNode : function(aNode) { for (var i = this.rowCount - 1; i >= 0; i--) { if (this.nodeMatches(aNode, this.table[i])) { this.selection.select(i); this.treebox.ensureRowIsVisible(i); } } }, getComparator : function() { var col = this.sortMenuItemMap[this.getComparatorKey()]; return getComparatorFunc(col); }, sortTable : function sortTable() { /* * Remember the currently selected node so we can restore it after the sort */ var selectedNodeBeforeSort = this.getSelectedNode(); /* * Close any open nodes, remembering them so that they can be reopened afterwards. * Closing is required because open nodes break the sort order */ var nodesOpenedBeforeSort = this.closeOpenedNodes(); var comparator = this.getComparator(); if (comparator) { yDebug.print("******************* sorting table of length:" + this.table.length); this.table = this.table.sort(comparator); } for (var i = 0; i < this.table.length; ++i) { this.table[i].isDirty = false; } this.openNodes(nodesOpenedBeforeSort); if (selectedNodeBeforeSort) { if (theXBL._popupShowing) { // sidebar or popup currently visible this.selectNode(selectedNodeBeforeSort); } } this.treebox.invalidate(); }, mergeTable : function mergeTable() { /* * Remember the currently selected node so we can restore it after the sort */ var selectedNodeBeforeSort = this.getSelectedNode(); /* * Close any open nodes, remembering them so that they can be reopened afterwards. * Closing is required because open nodes break the sort order */ var nodesOpenedBeforeSort = this.closeOpenedNodes(); var comparator = this.getComparator(); if (comparator) { var tTable = new Array(); for (var i = 0; i < this.table.length; ++i) { var obj = this.table[i]; if (obj.isDirty) { obj.isDirty = false; tTable[tTable.length] = obj; this.table.splice(i, 1); } } if (tTable.length <= 0) { return; } tTable.sort(comparator); var tableIndex = this.table.length - 1; var tTableIndex = tTable.length - 1; for (var mergedTableIndex = this.table.length + tTable.length - 1; mergedTableIndex >= 0; --mergedTableIndex) { if (tableIndex < 0) { // table exhausted this.table[mergedTableIndex] = tTable[tTableIndex]; --tTableIndex; continue; } if (tTableIndex < 0) { // tTable exhausted this.table[mergedTableIndex] = this.table[tableIndex]; --tableIndex; continue; } var rv = comparator(this.table[tableIndex], tTable[tTableIndex]); if (rv >= 0) { this.table[mergedTableIndex] = this.table[tableIndex]; --tableIndex; continue; } else { this.table[mergedTableIndex] = tTable[tTableIndex]; --tTableIndex; continue; } } } this.openNodes(nodesOpenedBeforeSort); if (selectedNodeBeforeSort) { if (theXBL._popupShowing) { // sidebar or popup currently visible this.selectNode(selectedNodeBeforeSort); } } this.treebox.invalidate(); }, isContainer : function(row) { return true; }, isContainerEmpty : function(row) { return this.table[row].parentIndex >= 0; }, isContainerOpen : function(row) { return this.table[row].isOpen; }, isSeparator : function(row) { return false; }, isSorted : function(row) { return false; }, getCellText : function(row, col) { return this.table[row][col.id]; }, getParentIndex : function(row) { return this.table[row].parentIndex || -1; }, getImageSrc : function(row, col) { return this.table[row].icon; }, getLevel : function(row) { return this.table[row].Level; }, getRowProperties : function(row, props) {}, getColumnProperties : function(col, props) {}, getCellProperties : function(row, col, props) {} }; methods.addProperties.call(CustomTreeView.prototype, methods); this.tagsTreeData = { getNodes : function(tag, comparator) { var nodes = tag ? tag.getRelatedTags() : Tag.getAll(); if (comparator) { nodes = nodes.sort(comparator); } return nodes; }, containsNode : function(tag) { return tag.NumBookmarks > 0; } }; this.tagsTreeDataSearch = function(storeNumber, searchQuery) { return { searchQuery : searchQuery.toLowerCase(), getNodes : function(tag, comparator) { var nodes = tag ? tag.getRelatedTags() : bookmarksStore.getTagsSearchResults(storeNumber, {}).map(Tag.getNew); if (comparator) { nodes = nodes.sort(comparator); } return nodes; }, containsNode : function(tag) { return tag.NumBookmarks > 0 && tag.matchesSearchQuery(this.searchQuery); } }; }; /****************************************************************************** tagsTreeView ******************************************************************************/ this.tagsTreeView = this.tagsTree.view = new CustomTreeView({ data : this.tagsTreeData, defaultComparator : getComparatorFunc("Name"), countElem : tagsCount, getCellValue : function() { return "_yb_tag_entity"; }, // required for context menu getComparatorKey : function() { return tagsSortMenu.selectedItem.id; }, sortMenuItemMap : { "ybsidebar-tags-sort-menu-alpha" : "Name", "ybsidebar-tags-sort-menu-freq" : "NumBookmarks" }, initFunction : function() { this.listenForEvent(tagsSortMenu, "ValueChange", "sortTable"); tagsSortMenu.addEventListener("ValueChange", function (event) { theXBL._onSortSelect(event); }, false); if (tagsSortMenu.selectedItem) this.sortTable(); }, updateTag : function(tagName, operation) { var row = this.getRowByName(tagName), tag = null; var tag = new Tag(tagName, null, true); if (row >= 0) { if (this.nodeFiltered(tag)) { this.table.splice(row, 1); } else { this.table[row] = tag; } } else if ("assert" === operation) { if (!this.nodeFiltered(tag)) { this.table[this.table.length] = tag; } } } }); /****************************************************************************** bookmarksTreeView ******************************************************************************/ this.bookmarksTreeData = { getNodes : function(livemark) { if (!livemark) { var tag = tagsTreeView.getSelectedNode(); return tag ? getBookmarksForTags(tag.getAncestors()) : Bookmark.getAll(); } else { return livemark.getLivemarkChildren(); } }, containsNode : function(bookmark) { var tag = tagsTreeView.getSelectedNode(); return tag ? bookmark.hasTags(tag.getAncestors()) : true; } }; this.bookmarksTreeDataSearch = function(storeNumber, searchQuery) { return { searchQuery : searchQuery.toLowerCase(), getNodes : function(livemark) { if (!livemark) { var tag = tagsTreeView.getSelectedNode(); return tag ? getBookmarksForTags(tag.getAncestors()) : bookmarksStore.getBookmarksSearchResults(storeNumber, {}).map(Bookmark.getNew); } else { return livemark.getLivemarkChildren(); } }, containsNode : function(bookmark) { var tag = tagsTreeView.getSelectedNode(); if (tag) { return bookmark.hasTags(tag.getAncestors()); } if (searchQuery.length > 0) { return bookmark.matchesSearchQuery(searchQuery); } } }; }; this.bookmarksTreeView = this.bookmarksTree.view = new CustomTreeView({ data : this.bookmarksTreeData, defaultComparator : getComparatorFunc("added_date"), countElem : bookmarksCount, isContainer : function(row) { return this.table[row].isLivemark(); }, getCellValue : function(row, col) { return this.table[row].url; }, onTagSelect : function() { this.loadTable(); this.sortTable(); }, getComparatorKey : function() { return bookmarksSortMenu.selectedItem.id; }, sortMenuItemMap : { "ybsidebar-bookmarks-sort-menu-alpha" : "Name", "ybsidebar-bookmarks-sort-menu-site" : "url", "ybsidebar-bookmarks-sort-menu-most-visited" : "visit_count", "ybsidebar-bookmarks-sort-menu-last-visited" : "last_visited", "ybsidebar-bookmarks-sort-menu-last-added" : "added_date" }, getImageSrc : function(row, col) { if ("note" === col.id) { var bookmark = this.table[row]; if (bookmark.desc && !bookmark.shared) { return "chrome://ybookmarks/skin/privateNote.gif"; } else if (!bookmark.shared) { return "chrome://ybookmarks/skin/private.gif"; } else if (bookmark.desc) { return "chrome://ybookmarks/skin/note.gif"; } } if (!(this.table[row].isLivemark()) && "Name" === col.id) { var bookmark = this.table[row]; if(bookmark && bookmark.icon) { return bookmark.icon; } } return null; }, getCellProperties : function(row, col, props) { if (this.table[row].isLivemark()) { props.AppendElement(ybookmarksUtils.atomService.getAtom("livemark")); } }, initFunction : function() { this.listenForEvent(bookmarksSortMenu, "ValueChange", "sortTable"); this.listenForEvent(tagsTree, "select", "onTagSelect"); bookmarksSortMenu.addEventListener("ValueChange", function (event) { theXBL._onSortSelect(event); }, false); if (bookmarksSortMenu.selectedItem) this.sortTable(); }, getRowByUrl : function(url) { return this.linearSearch(function(x) { return x.url == url; }); }, deleteBookmark : function(url) { var row = this.getRowByUrl(url); if (row >= 0) { this.deleteNode(row); } }, updateBookmark : function(resourceUri, url) { var row = this.getRowByUrl(url), bookmark = null; var resource = gRdfService.GetResource(resourceUri); var bookmark = new Bookmark(resource, null, true); if (row >= 0) { if (this.nodeFiltered(bookmark)) { yDebug.print("Bookmark filtered " + url); this.table.splice(row, 1); } else { this.table[row] = bookmark; } } else { if ("LiveBookmark" !== bookmarksStore.resolveBookmarkResourceType(resource)) { if (!this.nodeFiltered(bookmark)) { this.table[this.table.length] = bookmark; } } } } }); this.getElementByAnonid("ybsidebar-search-reset").addEventListener("click", function() { theXBL.reset(); }, false); //set the login state this._setLoginState(); if (this.parentNode.nodeName == "popup") { this._splitter.setAttribute("ybookmarkPopup", "true"); this._showSidebarButton.hidden = false; this.enableSidebarSwitch(true); this.tagsSortMenu.collapsed = true; this.bookmarksSortMenu.collapsed = true; this.tagsTree.removeAttribute("contextmenu"); this.bookmarksTree.removeAttribute("contextmenu"); } //set the last searched keyword var keyword = this._getLastSidebarSearchValue(); if (keyword) { this.search(keyword); this.iconHandler(keyword); this.setSearchBoxSelect(); } this.observedSubjects = ["ybookmark.userChanged", "ybookmark.importBookmarks", "ybookmark.syncBegin", "ybookmark.syncDone", "ybookmarkSearch.begin", "ybookmarkSearch.end", "ybookmarkSearch.inProgress", "ybookmark.bookmarkDeleted"]; for (var i = 0; i < this.observedSubjects.length; i++) { this.addObserver(this.observedSubjects[i]); } bookmarksDataSource.AddObserver(this); this._searchProgressMeter.hidden = true; // set the sort orders var bookmarksSortIndex = 0; try { bookmarksSortIndex = this._prefs.getIntPref("extensions.ybookmarks@yahoo.sidebar.bookmarksSortSelectedIndex"); } catch (e) { } this.bookmarksSortMenu.selectedIndex = bookmarksSortIndex; var tagsSortIndex = 0; try { tagsSortIndex = this._prefs.getIntPref("extensions.ybookmarks@yahoo.sidebar.tagsSortSelectedIndex"); } catch (e) { } this.tagsSortMenu.selectedIndex = tagsSortIndex; // Below is a hack for the popup overlay // apparently, if you mouseover a menulist (sort orders), they'll popup without a click if (this.parentNode.nodeName == "popup") { var popupOnPopupShowing = function(event) { if (this.yb_allowSortPopup) { this.menupopup.position = "after_start"; } else { event.preventDefault(); } }; var popupOnClick = function(event) { if (this.yb_allowSortPopup == false ) { this.yb_allowSortPopup = true; this.menupopup.showPopup(self, -1, -1, "popup", "bottomleft", "topleft"); this.yb_allowSortPopup = false; } }; this.tagsSortMenu.yb_allowSortPopup = false; this.tagsSortMenu.addEventListener("popupshowing", popupOnPopupShowing, true); this.tagsSortMenu.addEventListener("click", popupOnClick, true); this.bookmarksSortMenu.yb_allowSortPopup = false; this.bookmarksSortMenu.addEventListener("popupshowing", popupOnPopupShowing, true); this.bookmarksSortMenu.addEventListener("click", popupOnClick, true); } // show the URL over when mousing over login links this._loginMouseOverListener = { handleEvent: function(event) { var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]. getService(Components.interfaces.nsIWindowMediator); var recentWindow = wm.getMostRecentWindow("navigator:browser"); var url = event.target.getAttribute("url"); recentWindow.XULBrowserWindow.setOverLink(url); } }; this._loginMouseOutListener = { handleEvent: function(event) { var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]. getService(Components.interfaces.nsIWindowMediator); var recentWindow = wm.getMostRecentWindow("navigator:browser"); recentWindow.XULBrowserWindow.setOverLink(""); } }; var ss = Components.classes["@yahoo.com/socialstore/delicious;1"]. getService(Components.interfaces.nsISocialStore); var loginName = document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-login-status"); loginName.addEventListener("mouseover", this._loginMouseOverListener, false); loginName.addEventListener("mouseout", this._loginMouseOutListener, false); var loginDel = document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-login-status-3"); loginDel.setAttribute("url", deliciousService.getUrl()); loginDel.addEventListener("mouseover", this._loginMouseOverListener, false); loginDel.addEventListener("mouseout", this._loginMouseOutListener, false); var loginImage = document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-login-image"); loginImage.setAttribute("url", deliciousService.getUrl()); loginImage.addEventListener("mouseover", this._loginMouseOverListener, false); loginImage.addEventListener("mouseout", this._loginMouseOutListener, false); //Handles UI behaviour of querybox //Makes use of css ybsidebar-search2 with the attribute status taking 2 values. 'focus' and 'inactive'. this.blurQueryBox = { handleEvent: function(event) { var b = event.target; if(b) { b.setAttribute('status', 'inactive'); } } }; this.activateQueryBox = { handleEvent: function(event) { var b = event.target; if(b) { b.setAttribute('status', 'focus'); } } }; var queryBox = document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-search-query"); queryBox.setAttribute("status", "focus"); queryBox.addEventListener("blur", this.blurQueryBox, true); queryBox.addEventListener("focus", this.activateQueryBox, true); //Pinned or Unpinned Sidebar?, this call sets it this.initPinState(); //listen to select event of tagstree this.tagsTree.addEventListener("select", this.resetSearchIcon, false); ]]> </constructor> <destructor><![CDATA[ for (var i = 0; i < this.observedSubjects.length; i++) { this.removeObserver(this.observedSubjects[i]); } bookmarksDataSource.RemoveObserver(this); try { var loginName = document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-login-status"); loginName.removeEventListener("mouseover", this._loginMouseOverListener, false); loginName.removeEventListener("mouseout", this._loginMouseOutListener, false); } catch (e) {} try { var loginDel = document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-login-status-3"); loginDel.removeEventListener("mouseover", this._loginMouseOverListener, false); loginDel.removeEventListener("mouseout", this._loginMouseOutListener, false); } catch(e) {} try { var loginImage = document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-login-status-image"); loginImage.removeEventListener("mouseover", this._loginMouseOverListener, false); loginImage.removeEventListener("mouseout", this._loginMouseOutListener, false); } catch(e) {} try { var queryBox = document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-search-query"); queryBox.removeEventListener("blur", this.blurQueryBox, true); queryBox.removeEventListener("focus", this.activateQueryBox, true); } catch(e) {} if(!this._pinned) { this.removePinListeners(); } //hack to restore standard sidebar header var s = ybookmarksUtils.getTopWindow().document.getElementById("sidebar-box"); s.firstChild.hidden = false; //remove listening to select event of tagstree this.tagsTree.removeEventListener("select", this.resetSearchIcon, false); ]]></destructor> <field name="nextSyncTime">0</field> <field name="DEFAULT_BOOKMARKS_THRESHOLD">2000</field> <field name="SIDEBAR_SYNC_INTERVAL">2000</field> <field name="bookmarksStore">ybookmarksUtils.bookmarksStore</field> <field name="_socialStore">ybookmarksUtils.socialStore</field> <field name="_prefs">ybookmarksUtils.prefs</field> <field name="bookmarksDataSource">this.bookmarksStore.getDataSource();</field> <field name="searchDataSource">this.bookmarksStore.getSearchDataSource();</field> <field name="yTreeTagOriginalRef">"NC:YBookmarksTagRoot"</field> <field name="yTreeBmOriginalRef">"NC:BookmarksRoot"</field> <field name="tagsTree">null</field> <field name="bookmarksTree">null</field> <field name="_stringBundle">document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-stringbundle");</field> <field name="_showSidebarButton">document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-showSidebar");</field> <field name="_searchBox">document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-search-query");</field> <field name="_splitter">document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-tree-splitter");</field> <field name="_tagsLabelContainer">document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-tagsLabelContainer");</field> <field name="_bookmarksLabelContainer">document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-bookmarksLabelContainer");</field> <field name="_noTagsResultsBox">document.getAnonymousElementByAttribute(this, "anonid", "ybbookmarks-no-tags-results");</field> <field name="_noBookmarksResultsBox">document.getAnonymousElementByAttribute(this, "anonid", "ybbookmarks-no-bookmarks-results");</field> <field name="_searchProgressMeter">document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-search-progress-meter" );</field> <field name="tagsLabelContainerHeight">0</field> <!-- fields required for search progress bar functionality --> <!-- How many bookmarks are searched till now. Reset this value for every search --> <field name="_sofarSearched">0</field> <!-- Is tag search still running? --> <field name="_gotTagSearchEnd">false</field> <!-- Is bookmarks search still running? --> <field name="_gotBookmarkSearchEnd">false</field> <field name="dirtyTags">new Object();</field> <field name="dirtyBookmarks">new Object();</field> <field name="_popupShowing">true</field> <field name="_pinned">true</field> <field name="_timeout">0</field> <field name="_canCloseSideBar">false</field> <field name="tagIsSelected">false</field> <method name="getElementByAnonid"> <parameter name="anonid" /> <body><![CDATA[ return document.getAnonymousElementByAttribute(this, "anonid", anonid); ]]></body> </method> <!-- Following functions are for the pinned feature --> <method name="addPinListeners"> <body><![CDATA[ this.addEventListener("blur", this.sidebarBlur, true); this.addEventListener("focus", this.sidebarFocus, true); window.top.document.addEventListener("click", this.mouseListener, true); var info = Components.classes["@mozilla.org/xre/app-info;1"] .getService(Components.interfaces.nsIXULAppInfo); var ver = info.version.substring(0,2); //Listening for tabselect event, this covers tabclose,tabopen and tabswitch. if(ver == "2.") { //Works for FF2+ var container = window.top.document.getElementById("content").tabContainer; if(container) { container.addEventListener("TabSelect", this.timedClose, false); } } else if(ver == "1.") { var container = window.top.document.getElementById("content").mPanelContainer; if(container) { container.addEventListener("select", this.timedClose, false); } } //set sidebar pin button attributes var pinButton = document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-pin-button"); pinButton.setAttribute("class", "yb-nopin-button"); pinButton.setAttribute("tooltiptext", this._stringBundle.getString("extensions.ybookmarks.ybsidebar.header.pinButttonOpenLabel", "Click to keep this sidebar open")); ]]></body> </method> <method name="removePinListeners"> <body><![CDATA[ try { this.removeEventListener("blur", this.sidebarBlur, true); } catch(e) {} try { this.removeEventListener("focus", this.sidebarFocus, true); } catch(e) {} try { window.top.document.removeEventListener("click", this.mouseListener, true); } catch(e) {} var info = Components.classes["@mozilla.org/xre/app-info;1"] .getService(Components.interfaces.nsIXULAppInfo); var ver = info.version.substring(0,2); if(ver == "2.") { //Works for FF2+ var container = window.top.document.getElementById("content").tabContainer; if(container) { try { container.removeEventListener("TabSelect", this.timedClose, false); } catch(e) {} } } else if(ver == "1.") { var container = window.top.document.getElementById("content").mPanelContainer; if(container) { try { container.removeEventListener("select", this.timedClose, false); } catch(e) {} } } var pinButton = document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-pin-button"); pinButton.setAttribute("class", "yb-pin-button"); pinButton.setAttribute("tooltiptext", this._stringBundle.getString("extensions.ybookmarks.ybsidebar.header.pinButttonHideLabel", "Click to automatically hide this sidebar")); ]]></body> </method> <method name="tryClosingSidebar"> <body><![CDATA[ if(this._canCloseSideBar) { this._canCloseSideBar = false; window.clearTimeout(this._timeout); window.top.ybsidebar.closeSidebar(); } ]]></body> </method> <method name="sidebarBlur"> <body><![CDATA[ this._canCloseSideBar = true; var me = this; _timeout = setTimeout(function() { me.tryClosingSidebar(); }, 500); ]]></body> </method> <method name="timedClose"> <body><![CDATA[ setTimeout(window.top.ybsidebar.closeSidebar(),500); ]]></body> </method> <method name="sidebarFocus"> <body><![CDATA[ window.clearTimeout(this._timeout); this._canCloseSideBar = false; ]]></body> </method> <method name="mouseListener"> <parameter name="event" /> <body><![CDATA[ var sidebar = window.top.document.getElementById("sidebar"); if(sidebar) { if(sidebar.boxObject) { if((event.screenX >= sidebar.boxObject.screenX) && (event.screenX <= (sidebar.boxObject.screenX + sidebar.boxObject.width + 10)) && (event.screenY >= sidebar.boxObject.screenY) && (event.screenY <= (sidebar.boxObject.screenY + sidebar.boxObject.height))) { return true; } else { if(!window.top.ybsidebar._pinned) { setTimeout(window.top.ybsidebar.closeSidebar(),500); } } } } ]]></body> </method> <method name="mouseListener"> <parameter name="event" /> <body><![CDATA[ var sidebar = window.top.document.getElementById("sidebar"); if(sidebar) { if(sidebar.boxObject) { if((event.screenX >= sidebar.boxObject.screenX) && (event.screenX <= (sidebar.boxObject.screenX + sidebar.boxObject.width + 10)) && (event.screenY >= sidebar.boxObject.screenY) && (event.screenY <= (sidebar.boxObject.screenY + sidebar.boxObject.height))) { return true; } else { if(!window.top.ybsidebar._pinned) { setTimeout(window.top.ybsidebar.closeSidebar(),500); } } } } ]]></body> </method> <method name="initPinState"> <body><![CDATA[ try { this._pinned = this._prefs.getBoolPref( "extensions.ybookmarks@yahoo.sidebar.pinned" ); } catch ( e ) {} if(!this._pinned) { //Add listeners for pin this.addPinListeners(); } ]]></body> </method> <method name="togglePinState"> <body><![CDATA[ //toggle pin state if(this._pinned == true) { this._pinned = false; } else { this._pinned = true; } this._prefs.setBoolPref("extensions.ybookmarks@yahoo.sidebar.pinned", this._pinned); var pinButton = document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-pin-button"); if(!this._pinned) { //Add listeners for pin this.addPinListeners(); } else { this.removePinListeners(); } this.setSearchBoxFocus(); ]]></body> </method> <!-- end of pin functions --> <method name="periodicUpdate"> <body><![CDATA[ /* * Process dirty tags */ var dirtyTags = this.dirtyTags; var tagsTreeView = this.tagsTreeView; var needSort = false; tagsTreeView.treebox.beginUpdateBatch(); for (var tag in dirtyTags) { if (dirtyTags.hasOwnProperty(tag)) { tagsTreeView.updateTag(tag, dirtyTags[tag]); needSort = true; } } yDebug.print("periodicUpdate: calling tagsTreeView.sortTable..."); if (needSort) { tagsTreeView.mergeTable(); } tagsTreeView.treebox.endUpdateBatch(); tagsTreeView.updateCount(); this.dirtyTags = {}; /* * Process dirty bookmarks */ var dirtyBookmarks = this.dirtyBookmarks; needSort = false; var bookmarksTreeView = this.bookmarksTreeView; bookmarksTreeView.treebox.beginUpdateBatch(); for (var bookmark in dirtyBookmarks) { if (dirtyBookmarks.hasOwnProperty(bookmark)) { bookmarksTreeView.updateBookmark(bookmark, dirtyBookmarks[bookmark]); needSort = true; } } yDebug.print("periodicUpdate: calling bookmarksTreeView.sortTable..."); if (needSort) { bookmarksTreeView.mergeTable(); } bookmarksTreeView.treebox.endUpdateBatch(); bookmarksTreeView.updateCount(); this.dirtyBookmarks = {}; yDebug.print("periodicUpdate: done"); ]]></body> </method> <method name="schedulePeriodicUpdate"> <body><![CDATA[ /** ** Schedule a periodic sync at next multiple of ** SIDEBAR_SYNC_INTERVAL if one isn't already ** scheduled **/ var currTime = new Date().getTime(); var nextSyncTime = Math.ceil(currTime / this.SIDEBAR_SYNC_INTERVAL) * this.SIDEBAR_SYNC_INTERVAL; if (nextSyncTime > this.nextSyncTime) { var me = this; setTimeout(function() { me.periodicUpdate(); }, currTime - nextSyncTime); this.nextSyncTime = nextSyncTime; } ]]></body> </method> <method name="processAssertOrUnassert"> <parameter name="operation" /> <parameter name="aDataSource" /> <parameter name="aSubject" /> <parameter name="aPredicate" /> <parameter name="aTarget" /> <body><![CDATA[ var isDirty = false; var url = null; if (this.removingAllData) return; if (aDataSource == this.bookmarksDataSource) { if (aPredicate.EqualsNode(this.grscTag)) { var tagName = aTarget.QueryInterface(this.nsIRDFLiteral).Value; this.dirtyTags[tagName.toLowerCase()] = operation; isDirty = true; } else if (aPredicate.EqualsNode(this.grscUrl) && "unassert" === operation) { url = aTarget.QueryInterface(this.nsIRDFLiteral).Value; if (url) { this.bookmarksTreeView.deleteBookmark(url); isDirty = true; } } url = this.bookmarkResource.getUrl(aSubject); if (url) { this.dirtyBookmarks[aSubject.Value] = url; isDirty = true; } if (isDirty) { this.schedulePeriodicUpdate(); } } ]]></body> </method> <method name="onAssert"> <parameter name="aDataSource" /> <parameter name="aSubject" /> <parameter name="aPredicate" /> <parameter name="aTarget" /> <body><![CDATA[ this.processAssertOrUnassert("assert", aDataSource, aSubject, aPredicate, aTarget); ]]></body> </method> <method name="onUnassert"> <parameter name="aDataSource" /> <parameter name="aSubject" /> <parameter name="aPredicate" /> <parameter name="aTarget" /> <body><![CDATA[ this.processAssertOrUnassert("unassert", aDataSource, aSubject, aPredicate, aTarget); ]]></body> </method> <method name="onChange"> <parameter name="aDataSource" /> <parameter name="aSubject" /> <parameter name="aPredicate" /> <parameter name="aOldTarget" /> <parameter name="aNewTarget" /> <body><![CDATA[ this.processAssertOrUnassert("change", aDataSource, aSubject, aPredicate, aNewTarget); ]]></body> </method> <method name="onBeginUpdateBatch"> <parameter name="aDataSource" /> <body><![CDATA[ return true; ]]></body> </method> <method name="onEndUpdateBatch"> <parameter name="aDataSource" /> <body><![CDATA[ return true; ]]></body> </method> <method name="observe"> <parameter name="aSubject"/> <parameter name="aTopic"/> <parameter name="aData"/> <body> <![CDATA[ if (aTopic == "ybookmark.userChanged") { this._setLoginState(); } else if ( aTopic == "ybookmarkSearch.begin" ) { // show the only when bookmarks search started. We do start bookmark search before // tags search. if ( aData == "tags" ) return; this._showOrHideProgressmeter(); // reset all the flags this._sofarSearched = 0; this._gotBookmarkSearchEnd = false; this._gotTagSearchEnd = false; } else if ( aTopic == "ybookmarkSearch.end" ) { // wait for both tags and bookmarks search to finish before hiding the // the progressbar. if ( !this._gotTagSearchEnd ) this._gotTagSearchEnd = (aSubject.wrappedJSObject.type == "tags"); if ( !this._gotBookmarkSearchEnd ) this._gotBookmarkSearchEnd = (aSubject.wrappedJSObject.type == "bookmarks"); if ( this._gotBookmarkSearchEnd && this._gotTagSearchEnd ) { this._searchProgressMeter.value = 100; var meter = this._searchProgressMeter; // do not hide the progressbar immedietly. Wait for 900 milli seconds. // Should this be configurable? setTimeout( function() { meter.collapsed = true; meter.hidden = true; }, 900 ); } // If no results from tags search, show the no results pane. Otherwise hide the // the no results pane. if ( aSubject.wrappedJSObject.type == "tags" ) { if ( aSubject.wrappedJSObject.totalMatched == 0 ) { this._showNoSearchResults("tags", true); } else { this._showNoSearchResults("tags", false); } } // If no results from bookmarks search, show the no results pane. Otherwise hide the // the no results pane. if ( aSubject.wrappedJSObject.type == "bookmarks" ) { if ( aSubject.wrappedJSObject.totalMatched == 0 ) { this._showNoSearchResults("bookmarks", true); } else { this._showNoSearchResults("bookmarks", false); } } yDebug.print("************ b4 _populateTreesWithSearchResults: this._searchBox.value =\"" + this._searchBox.value + "\""); this._populateTreesWithSearchResults(aSubject.wrappedJSObject.type, this._searchBox.value); } else if ( aTopic == "ybookmarkSearch.inProgress" ) { // Calculate the percentage of search done. this._sofarSearched += aSubject.wrappedJSObject.sofar; this._searchProgressMeter.value = ( 100 * this._sofarSearched ) / aSubject.wrappedJSObject.total; } else if ( aTopic == "ybookmark.importBookmarks" ) { if (this._searchBox.value) { return; } aSubject.QueryInterface(Components.interfaces.nsISupportsString); if ((aSubject.data == "importProgress" && (aData == "complete" || aData == "failed")) || aSubject.data == "importError") { var tagsRef = this._getTreeRef("tags"); this.tagsTree.setAttribute("ref", tagsRef); var bookmarksRef = this._getTreeRef("bookmarks") this.bookmarksTree.setAttribute("ref", bookmarksRef); if (tagsRef.length) { this._showNoSearchResults("tags", false); this._showNoSearchResults("bookmarks", false); } else { this._showEmptyPane("tags"); this._showEmptyPane("bookmarks"); } } else { if (!this._hasBookmarks()) { this._showImportingPane("tags"); this._showImportingPane("bookmarks"); } else { var tagsRef = this._getTreeRef("tags"); this.tagsTree.setAttribute("ref", tagsRef); var bookmarksRef = this._getTreeRef("bookmarks") this.bookmarksTree.setAttribute("ref", bookmarksRef); if (tagsRef.length) { this._showNoSearchResults("tags", false); this._showNoSearchResults("bookmarks", false); } else { this._showEmptyPane("tags"); this._showEmptyPane("bookmarks"); } } } } else if ("ybookmark.syncBegin" === aTopic) { if ("remove-extra" === aData) { this.removingAllData = true; } } else if ("ybookmark.syncDone" === aTopic) { if ("remove-extra" === aData) { this.removingAllData = false; yDebug.print("*** Received \"remove-extra\" message; reloading both tree views"); this.tagsTreeView.loadTable(); this.bookmarksTreeView.loadTable(); } else { this.schedulePeriodicUpdate(); } if ("all-done" === aData) { this.tagsTreeView.sortTable(); } } else if ("ybookmark.bookmarkDeleted" === aTopic) { this.bookmarksTreeView.treebox.invalidate(); this.bookmarksTreeView.loadTable(); this.bookmarksTreeView.sortTable(); } ]]></body> </method> <method name="_populateTreesWithSearchResults"> <parameter name="type"/> <parameter name="searchTerm"/> <body><![CDATA[ yDebug.print("ybSidebarOverlay._populateTreesWithSearchResults: type = " + type + "; searchTerm = " + searchTerm); var storeNumber; if (this.parentNode.nodeName == "popup") { storeNumber = 2; } else { storeNumber = 1; } if (type == "tags") { this.tagsTreeView.setData(new this.tagsTreeDataSearch(storeNumber, searchTerm)); this.tagsTreeView.sortTable(); } else if (type == "bookmarks") { this.bookmarksTreeView.setData(new this.bookmarksTreeDataSearch(storeNumber, searchTerm)); this.bookmarksTreeView.sortTable(); } ]]></body> </method> <method name="_hasBookmarks"> <body><![CDATA[ var datasource = this.bookmarksStore.getDataSource(); var rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"]. getService(Components.interfaces.nsIRDFService); var rdfContainerUtils = Components.classes["@mozilla.org/rdf/container-utils;1"]. getService(Components.interfaces.nsIRDFContainerUtils); var bookmarksRoot = rdfContainerUtils.MakeSeq(datasource, rdfService.GetResource ( "NC:BookmarksRoot" )); var allBookmarkResources = bookmarksRoot.GetElements(); var counter = 0; while (allBookmarkResources.hasMoreElements()) { bookmarkResource = allBookmarkResources.getNext(); counter ++; if (counter > 1){ return true; } } return false; ]]></body> </method> <method name="_setLoginState"> <body><![CDATA[ var username = this._socialStore.getUserName(); var element = document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-login-status"); try{ element.removeEventListener("click", this._login, true); } catch(e) {} if (username) { var url = deliciousService.getUrl(username); element.removeAttribute("class"); element.setAttribute("value", username); element.setAttribute("onclick", "_openUrl(event, '" + url + "')"); element.setAttribute("class", "ysidebar-textlink"); element.setAttribute("linktype", "standard"); element.setAttribute("url", url); } else { var ss = Components.classes["@yahoo.com/socialstore/delicious;1"]. getService(Components.interfaces.nsISocialStore); element.addEventListener("click", this._login, true); element.setAttribute("class", "ysidebar-textlink"); element.setAttribute("value", this._stringBundle.getString("ybookmarks.login", [username])); element.setAttribute("url", ss.login_url); } ]]></body> </method> <method name="search"> <parameter name="input"/> <body><![CDATA[ this._searchBox.value = input; this._search(input); this.setSearchBoxFocus(); ]]></body> </method> <method name="setSearchBoxFocus"> <body><![CDATA[ //hack to hide standard sidebar header var s = ybookmarksUtils.getTopWindow().document.getElementById("sidebar-box"); s.firstChild.hidden = true; this._searchBox.focus(); ]]></body> </method> <method name="setSearchBoxSelect"> <body><![CDATA[ if (this._searchBox.value.length) { this._searchBox.select(); } this.setSearchBoxFocus(); ]]></body> </method> <method name="enableSidebarSwitch"> <parameter name="bool"/> <body><![CDATA[ if (!this._showSidebarButton) this._showSidebarButton = document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-showSidebar"); if (bool) { this._showSidebarButton.disabled = false; } else { this._showSidebarButton.disabled = true; } ]]></body> </method> <method name="_openYBSidebar"> <body><![CDATA[ if (this.parentNode.nodeName == "popup") { toggleSidebar("viewYBookmarksSidebar", true); setTimeout(function(keyword) { var sidebar = document.getElementById("sidebar"); if (sidebar) { var ybsidebars = sidebar.contentDocument.firstChild.getElementsByTagName("ybsidebar"); if (ybsidebars.length) { ybsidebars[0].search(keyword); } } }, 20, this._searchBox.value); this._shouldClosePopup(false); } ]]></body> </method> <method name="_setLastSidebarSearchValue"> <parameter name="keyword"/> <body><![CDATA[ if (this.parentNode.nodeName != "popup") { window.top.ybsidebar.lastSidebarSearchValue = keyword; } else { ybsidebar.lastSidebarSearchValue = keyword; } ]]></body> </method> <method name="_getLastSidebarSearchValue"> <body><![CDATA[ if (this.parentNode.nodeName != "popup") { return window.top.ybsidebar.lastSidebarSearchValue; } else { return ybsidebar.lastSidebarSearchValue; } ]]></body> </method> <method name="setPopupSize"> <body><![CDATA[ if (this.parentNode.nodeName == "popup") { //set height //overlay.css .ybsidebar-tree-container var minTreesContainerHeight = 335; var windowHeight = document.documentElement.boxObject.height; var treesContainer = document.getAnonymousElementByAttribute(this, "class", "ybsidebar-tree-container"); var newTreesContainerHeight = parseInt(windowHeight) - 225; if (newTreesContainerHeight > minTreesContainerHeight) { treesContainer.setAttribute("minheight", newTreesContainerHeight); treesContainer.setAttribute("maxheight", newTreesContainerHeight); } else { treesContainer.setAttribute("minheight", minTreesContainerHeight); treesContainer.setAttribute("maxheight", minTreesContainerHeight); } var tagsTreeContainer = this.tagsTree.parentNode.parentNode; var tagsTreeContainerHeight = tagsTreeContainer.getAttribute("minheight"); if (tagsTreeContainerHeight) { treesContainerHeight = treesContainer.getAttribute("minheight"); if (parseInt(tagsTreeContainerHeight) > parseInt(treesContainerHeight)) { var newTreeHeight = treesContainerHeight - (22 + (this.tagsLabelContainerHeight * 2)); tagsTreeContainer.setAttribute("minheight", newTreeHeight); tagsTreeContainer.setAttribute("maxheight", newTreeHeight); } } //set width this.setAttribute("minwidth", 250); this.setAttribute("maxwidth", 250); } ]]></body> </method> <method name="_createContextMenu"> <parameter name="event"/> <body><![CDATA[ var target = document.popupNode; var tree = this._getTree(target); if(!tree) { target.removeAttribute("open"); return false; } var row = tree.currentIndex; var col = tree.columns.getNamedColumn('Name'); var url = tree.view.getCellValue(row, col); var livemark = this._isCurrentLivemark(tree); if (!livemark && (tree.view.isContainer(row) || !url) && (url != "_yb_tag_entity")) { target.removeAttribute("open"); return false; } var menu = document.getAnonymousElementByAttribute( this, "id", "ybContextMenu" ); var i; if (url == "_yb_tag_entity") { // tag for( i = 0; i < menu.childNodes.length; ++i ) { ( menu.childNodes[ i ] ).hidden = true; } ( document.getAnonymousElementByAttribute( this, "anonid", "ybContextMenu-openContainer" ) ).hidden = false; ( document.getAnonymousElementByAttribute( this, "anonid", "ybContextMenu-openTag" ) ).hidden = false; } else if (livemark) { for( i = 0; i < menu.childNodes.length; ++i ) { ( menu.childNodes[ i ] ).hidden = true; } ( document.getAnonymousElementByAttribute( this, "anonid", "ybContextMenu-delete-bookmark" ) ).hidden = false; ( document.getAnonymousElementByAttribute( this, "anonid", "ybContextMenu-separator3" ) ).hidden = false; ( document.getAnonymousElementByAttribute( this, "anonid", "ybContextMenu-about" ) ).hidden = false; ( document.getAnonymousElementByAttribute( this, "anonid", "ybContextMenu-properties" ) ).hidden = false; } else { // normal bookmark for( i = 0; i < menu.childNodes.length; ++i ) { ( menu.childNodes[ i ] ).hidden = false; } ( document.getAnonymousElementByAttribute( this, "anonid", "ybContextMenu-openContainer" ) ).hidden = true; ( document.getAnonymousElementByAttribute( this, "anonid", "ybContextMenu-openTag" ) ).hidden = true; } return true; ]]></body> </method> <method name="_openURLIn"> <parameter name="event"/> <parameter name="tree"/> <parameter name="where"/> <body><![CDATA[ try { var row = tree.currentIndex; if (tree.view.rowCount <= 0) { return; } if (!tree.view.isContainer(row)) { var url = tree.view.getCellValue(row, tree.columns.getNamedColumn("Name")); if (url != "_yb_tag_entity") { event.target.setAttribute("type", "http://home.netscape.com/NC-rdf#Bookmark"); event.target.setAttribute("url", url); ybookmarksUtils.openBookmark(event, where); //hack if(!this._pinned) { this._canCloseSideBar = true; this.sidebarBlur(); } this._shouldClosePopup(true); } } } catch (e) { yDebug.print(e, YB_LOG_MESSAGE); } ]]></body> </method> <method name="_newBookmark"> <body><![CDATA[ if(this._pinned) { ybBookmarksMenu.newBookmark(); } else { //hack for unpinned mode alone Components.classes["@mozilla.org/observer-service;1"] .getService(Components.interfaces.nsIObserverService) .notifyObservers(null, "ybookmark.addBookmark", ""); window.top.ybsidebar.closeSidebar(); } ]]></body> </method> <method name="_editBookmark"> <parameter name="event"/> <parameter name="tree"/> <body><![CDATA[ var row = tree.currentIndex; var url = tree.view.getCellValue(row, tree.columns.getNamedColumn('Name')); if(this._pinned) { yAddBookMark.open(url); } else { //trick for unpinned mode alone Components.classes["@mozilla.org/observer-service;1"] .getService(Components.interfaces.nsIObserverService) .notifyObservers(null, "ybookmark.addBookmark", url); window.top.ybsidebar.closeSidebar(); } ]]></body> </method> <method name="_moreAbout"> <parameter name="event"/> <parameter name="tree"/> <body><![CDATA[ try { var row = tree.currentIndex; var url = tree.view.getCellValue(row, tree.columns.getNamedColumn('Name')); var livemark = this._isCurrentLivemark(tree); if (livemark || !tree.view.isContainer(row)) { event.target.setAttribute("type", "http://home.netscape.com/NC-rdf#Bookmark"); event.target.setAttribute("url", deliciousService.getMoreAboutUrl(url)); ybookmarksUtils.openBookmark(event, "current"); this._shouldClosePopup(true); } } catch (e) { yDebug.print( "ybSidebarOverlay._moreAbout(): " + e, YB_LOG_MESSAGE); } ]]></body> </method> <method name="_openTag"> <parameter name="event"/> <parameter name="tree"/> <body><![CDATA[ try { var row = tree.currentIndex; var value = tree.view.getCellText( row, ( tree.columns ).getNamedColumn( 'Name' ) ); ybookmarksUtils.openTag(value, event); } catch ( e ) { yDebug.print( "ybSidebarOverlay._openTag() exception: " + e, YB_LOG_MESSAGE); } ]]></body> </method> <!-- This method opens all children in the bookmark view. --> <method name="_openContainer"> <parameter name="event"/> <parameter name="tree"/> <body><![CDATA[ try { var row = tree.currentIndex; var value = tree.view.getCellValue( row, ( tree.columns ).getNamedColumn( 'Name' ) ); if( value == "_yb_tag_entity" ) { if( tree.view.isContainerOpen( row ) ) { var urls = new Array(); var i = row + 1; while( i < tree.view.rowCount ) { if( tree.view.getParentIndex( i ) != row ) { break; } value = tree.view.getCellValue( i, ( tree.columns ).getNamedColumn( 'Name' ) ); urls.push( value ); ++i; } YBtabsOpener.openURLsInNewTab( urls ); } else { tree.view.toggleOpenState( row ); this._openContainer( event, tree ); } } } catch ( e ) { yDebug.print( "ybSidebarOverlay._openContainer() exception: " + e, YB_LOG_MESSAGE); } ]]></body> </method> <!-- This method opens all bookmarks currently visible in the bookmark view. --> <method name="_openBookmarks"> <parameter name="event"/> <parameter name="tree"/> <body><![CDATA[ try { var urls = new Array(); for(i = 0; i < this.bookmarksTreeView.table.length; ++i) { var bm = this.bookmarksTreeView.table[i]; if (!bm.isLivemark()) { urls.push(bm.url); } } YBtabsOpener.openURLsInNewTab( urls ); } catch ( e ) { yDebug.print( "ybSidebarOverlay._openBookmarks() exception: " + e, YB_LOG_MESSAGE); } ]]></body> </method> <method name="_openHome"> <parameter name="event"/> <body><![CDATA[ var element = event.target; while (element) { if (element.nodeName == "ybsidebar") { break; } element = element.parentNode; } event.target.setAttribute("type", "http://home.netscape.com/NC-rdf#Bookmark"); event.target.setAttribute("url", deliciousService.getUrl()); ybookmarksUtils.openBookmark(event, "current"); element._shouldClosePopup(true); ]]></body> </method> <method name="_openUrl"> <parameter name="event"/> <parameter name="url"/> <body><![CDATA[ var element = event.target; while (element) { if (element.nodeName == "ybsidebar") { break; } element = element.parentNode; } event.target.setAttribute("type", "http://home.netscape.com/NC-rdf#Bookmark"); event.target.setAttribute("url", url); ybookmarksUtils.openBookmark(event, "current"); element._shouldClosePopup(true); ]]></body> </method> <method name="_login"> <parameter name="event"/> <body><![CDATA[ var element = event.target; while (element) { if (element.nodeName == "ybsidebar") { break; } element = element.parentNode; } event.target.setAttribute("type", "http://home.netscape.com/NC-rdf#Bookmark"); event.target.setAttribute("url", deliciousService.getLoginUrl()); ybookmarksUtils.openBookmark(event, "current"); element._shouldClosePopup(true); ]]></body> </method> <method name="_deleteBookmark"> <parameter name="event"/> <parameter name="tree"/> <body><![CDATA[ this._shouldClosePopup(false); /* if( !YBidManager.isUserLoggedIn() ) { YBidManager.promptUserLogin(); return; }*/ var row = tree.currentIndex; var url = tree.view.getCellValue(row, tree.columns.getNamedColumn('Name')); //We need to hack here to retain sidebar in unpinned mode var flipped = false; if(!this._pinned) { flipped = true; } if(flipped) { this.removePinListeners(); } //show UI ybBookmarksMenu.deleteBookmark(url); // tree.treeBoxObject.invalidate(); /** * Hack was added to refresh treeboxobject which is not getting updated even after deleting a bookmark */ window.setTimeout(function () { tree.treeBoxObject.invalidate(); }, 600); if(flipped) { //Add all listeners for pin this.addPinListeners(); } //end of hack /*this.bookmarksStore.deleteBookmark(url); var post = { url : url }; post.wrappedJSObject = post; this.bookmarksStore.addTransaction("deleteBookmark", 0, post); var syncService = Components.classes["@mozilla.org/ybookmarks-sync-service;1"]. getService(Components.interfaces.nsIYBookmarkSyncService); syncService.processTransactions(); */ ]]></body> </method> <method name="_showOrHideProgressmeter"> <body><![CDATA[ var threshold = this.DEFAULT_BOOKMARKS_THRESHOLD; try { threshold = this._prefs.getIntPref( "extensions.ybookmarks@yahoo.bookmark.threshold" ); } catch ( e ) { } if ( this.bookmarksStore.getTotalBookmarks() > threshold ) { var meter = this._searchProgressMeter; meter.value = 0; meter.collapsed = false; meter.hidden = false; } else { var meter = this._searchProgressMeter; meter.collapsed = true; meter.hidden = true; } ]]></body> </method> <!-- Following 2 functions are for setting the right icons --> <method name="iconHandler"> <parameter name="aInput"/> <body><![CDATA[ if(aInput == "") { this.getElementByAnonid("ybsidebar-search-reset").image = "chrome://ybookmarks/skin/searchIcon.gif"; } else { this.getElementByAnonid("ybsidebar-search-reset").image = "chrome://ybookmarks/skin/searchReset.gif"; } //this.getElementByAnonid("ybsidebar-search-query").setAttribute('status', 'focus'); ]]></body> </method> <method name="reseticonHandler"> <parameter name="aInput"/> <body><![CDATA[ var input = this.getElementByAnonid("ybsidebar-search-query").value; if(input == "" && !this.tagIsSelected) { this.getElementByAnonid("ybsidebar-search-reset").image = "chrome://ybookmarks/skin/searchIcon.gif"; } else { if(aInput == 'hover') { this.getElementByAnonid("ybsidebar-search-reset").image = "chrome://ybookmarks/skin/searchReset.gif"; } else { this.getElementByAnonid("ybsidebar-search-reset").image = "chrome://ybookmarks/skin/searchReset.gif"; } } ]]></body> </method> <method name="resetSearchIcon"> <body><![CDATA[ try { var sidebar = this.parentNode.parentNode.parentNode.parentNode.parentNode; sidebar.tagIsSelected = true; document.getAnonymousElementByAttribute(sidebar, "anonid", "ybsidebar-search-reset").image = "chrome://ybookmarks/skin/searchReset.gif"; } catch(e) {} ]]></body> </method> <method name="_search"> <parameter name="aInput"/> <body><![CDATA[ var storeNumber; if (this.parentNode.nodeName == "popup") { storeNumber = 2; } else { storeNumber = 1; } this._setLastSidebarSearchValue(aInput); if (!aInput) { this.reset(); } else { this._showOrHideProgressmeter(); this._showNoSearchResults("tags", false); this._showNoSearchResults("bookmarks", false); this.bookmarksStore.searchBookmarks(aInput, storeNumber); this.bookmarksStore.searchTags(aInput, storeNumber); } ]]></body> </method> <method name="reset"> <body><![CDATA[ this._searchBox.value =""; this._setLastSidebarSearchValue(""); this.tagsTreeView.setData(this.tagsTreeData); this.tagsTreeView.clearSelection(); this.tagsTreeView.sortTable(); this._showNoSearchResults("tags", false); this.bookmarksTreeView.setData(this.bookmarksTreeData); this.bookmarksTreeView.clearSelection(); this.bookmarksTreeView.sortTable(); this._showNoSearchResults("bookmarks", false); this.tagIsSelected = false; ]]></body> </method> <method name="_showNoSearchResults"> <parameter name="type"/> <parameter name="show"/> <body><![CDATA[ var index = show? 1 : 0; if (type == "tags") { var deck = document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-tags-deck"); deck.setAttribute("selectedIndex", index); this._noTagsResultsBox.firstChild.setAttribute("selectedIndex", 0); this._noTagsResultsBox.collapsed = !show; } else if (type == "bookmarks") { var deck = document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-bookmarks-deck"); deck.setAttribute("selectedIndex", index); this._noBookmarksResultsBox.firstChild.setAttribute("selectedIndex", 0); this._noBookmarksResultsBox.collapsed = !show; } ]]></body> </method> <method name="_showEmptyPane"> <parameter name="type"/> <body><![CDATA[ var index = 1; if (type == "tags") { var deck = document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-tags-deck"); deck.setAttribute("selectedIndex", index); this._noTagsResultsBox.firstChild.setAttribute("selectedIndex", 1); this._noTagsResultsBox.collapsed = false; } else if (type == "bookmarks") { var deck = document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-bookmarks-deck"); deck.setAttribute("selectedIndex", index); this._noBookmarksResultsBox.firstChild.setAttribute("selectedIndex", 1); this._noBookmarksResultsBox.collapsed = false; } ]]></body> </method> <method name="_showImportingPane"> <parameter name="type"/> <body><![CDATA[ var index = 1; if (type == "tags") { var deck = document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-tags-deck"); deck.setAttribute("selectedIndex", index); this._noTagsResultsBox.firstChild.setAttribute("selectedIndex", 2); this._noTagsResultsBox.collapsed = false; } else if (type == "bookmarks") { var deck = document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-bookmarks-deck"); deck.setAttribute("selectedIndex", index); this._noBookmarksResultsBox.firstChild.setAttribute("selectedIndex", 2); this._noBookmarksResultsBox.collapsed = false; } ]]></body> </method> <method name="_searchWeb"> <parameter name="engine"/> <body><![CDATA[ var url; if (engine == "yahoo") url = "http://search.yahoo.com/search?p=" + encodeURIComponent( this._searchBox.value ) + "&ei=UTF-8"; else url = deliciousService.getSearchUrl(this._searchBox.value); openUILinkIn ( url, "current"); this._shouldClosePopup(false); ]]></body> </method> <method name="_getTree"> <parameter name="aElement"/> <body><![CDATA[ var parentNode = aElement; var elementName; while (parentNode) { elementName = parentNode.nodeName; if (elementName == "tree" || elementName == "xul:tree") { return parentNode; } parentNode = parentNode.parentNode; } return null; ]]></body> </method> <method name="_changeOpenState"> <parameter name="tree"/> <parameter name="row"/> <parameter name="openState"/> <body><![CDATA[ if (row < 0 || !tree.view.isContainer(row)) { return false; } if (tree.view.isContainerOpen(row) != openState) { tree.view.toggleOpenState(row); if (row == tree.currentIndex) { var event = document.createEvent('Events'); event.initEvent('OpenStateChange', true, true); tree.dispatchEvent(event); } return true; } return false; ]]></body> </method> <method name="_shouldClosePopup"> <parameter name="delay"/> <body><![CDATA[ try{ if (this.parentNode.nodeName == "popup") { if (delay) { setTimeout(function(popup) { popup.hidePopup(); window.document.popupNode = null; }, 250, this.parentNode); } else { setTimeout(function(popup) { popup.hidePopup(); window.document.popupNode = null; }, 0, this.parentNode); } } } catch(e){} ]]></body> </method> <method name="_isCurrentLivemark"> <parameter name="tree"/> <body><![CDATA[ var row = tree.currentIndex; var col = tree.columns.getNamedColumn('Name'); var props = Components.classes["@mozilla.org/supports-array;1"]. createInstance(Components.interfaces.nsISupportsArray); tree.view.getCellProperties(row, col, props); var as = Components.classes["@mozilla.org/atom-service;1"]. getService(Components.interfaces.nsIAtomService); var livemarkAtom = as.getAtom("livemark"); for (var i=0; i < props.Count(); i ++) { var p = props.GetElementAt(i); if (livemarkAtom.equals(p)) { return true; } } return false; ]]></body> </method> <method name="_getTreeRef"> <parameter name="type"/> <body><![CDATA[ var threshold = this.DEFAULT_BOOKMARKS_THRESHOLD; try { threshold = this._prefs.getIntPref( "extensions.ybookmarks@yahoo.bookmark.threshold" ); } catch ( e ) { } if ( this.bookmarksStore.getTotalBookmarks() > threshold ) { return ""; } else { if (type == "tags") { return this.yTreeTagOriginalRef; } else { return this.yTreeBmOriginalRef; } } ]]></body> </method> <method name="openItemOnEnter"> <parameter name="aEvent"/> <parameter name="aTree"/> <body><![CDATA[ var browserTarget = whereToOpenLink(aEvent); this._openURLIn( aEvent, aTree, browserTarget ); //hack if(!this._pinned) { this._canCloseSideBar = true; this.sidebarBlur(); } ]]></body> </method> <method name="openItemClick"> <parameter name="aEvent"/> <parameter name="aTree"/> <body><![CDATA[ var row = {}, col = {}, childElt = {}; this.bookmarksTreeView.treebox.getCellAt(aEvent.clientX, aEvent.clientY, row, col, childElt); yDebug.print("openItemClick: childElt.value = \"" + childElt.value + "\"; row.value = " + row.value); if ((row.value == -1) || (col.value == null)) { return; } if ("twisty" === childElt.value) return true; var browserTarget = whereToOpenLink(aEvent); this._openURLIn( aEvent, aTree, browserTarget ); //hack if(!this._pinned) { this._canCloseSideBar = true; this.sidebarBlur(); } ]]></body> </method> <method name="_onSearchKeyUp"> <parameter name="aEvent"/> <body><![CDATA[ switch(aEvent.keyCode) { case aEvent.DOM_VK_DOWN: var sidebar = aEvent.target.parentNode.parentNode.parentNode.parentNode; if (sidebar._noBookmarksResultsBox.collapsed) { var bookmarksTree = sidebar.bookmarksTree; bookmarksTree.view.selection.select(0); bookmarksTree.focus(); aEvent.preventDefault(); } break; default: } ]]></body> </method> <method name="_onSortSelect"> <parameter name="aEvent"/> <body><![CDATA[ var menu = aEvent.target; var pref; if (menu == this.bookmarksSortMenu) { pref = "extensions.ybookmarks@yahoo.sidebar.bookmarksSortSelectedIndex"; } else if (menu == this.tagsSortMenu) { pref = "extensions.ybookmarks@yahoo.sidebar.tagsSortSelectedIndex"; } if (pref) { var index = menu.selectedIndex; this._prefs.setIntPref(pref, index); } ]]></body> </method> <method name="lineWrapIntoVbox"> <parameter name="vbox" /> <parameter name="contentText" /> <body><![CDATA[ try { //yDebug.print("ybSidebarOverlay.xml::lineWrapIntoVbox():: Coming ", YB_LOG_MESSAGE); /* * Yes, it's lame that XUL won't allow us to have a * multi-line text field, so we have to resort to doing our * own word wrapping and putting each line in a separate * <xul:label> * (See http://blogs.acceleration.net/ryan/archive/2004/09/23/310.aspx) */ ybookmarksUtils.removeAllChildren(vbox); if (contentText.length > 0) { var arrLines = ybookmarksUtils.lineWrap(contentText, 31); for (var i = 0; i < arrLines.length; i++) { var lbl = document.createElement("label"); lbl.setAttribute("value", arrLines[i]); vbox.appendChild(lbl); } } } catch(e) { yDebug.print("ybSidebarOverlay.xml::lineWrapIntoVbox():: Exception - "+e, YB_LOG_MESSAGE); } ]]></body> </method> <method name="processClick"> <parameter name="event" /> <body><![CDATA[ //do below only if the parentNode is popup if (this.parentNode.nodeName != "popup") { return; } var tree = this._getTree(event.originalTarget); if (!tree) { return; } var topContainer = document.getAnonymousElementByAttribute(this, "anonid", "ybsidebar-topContainer"); //hack : the X, Y coordinate doesn't display properly, //we need the X Y from the browser window, not from the tree or popup var posX; var posY; event.stopPropagation(); event.preventDefault(); posX = this.boxObject.x + event.clientX; if (tree == this.tagsTree) { posY = this.boxObject.y + event.clientY + topContainer.boxObject.height + this._tagsLabelContainer.boxObject.height; } else { posY = this.boxObject.y + event.clientY + topContainer.boxObject.height + this.tagsTree.parentNode.parentNode.boxObject.height + this._splitter.boxObject.height + this._bookmarksLabelContainer.boxObject.height; } var row = { }, col = { }, obj = { }; var treeBoxObj = tree.treeBoxObject; treeBoxObj.getCellAt(posX, posY, row, col, obj); if ((row.value == -1) || (col.value == null)) { return; } //don't change the container's open state if it is a right click if (event.button != 2) { tree.view.selection.select(row.value); tree.view.selection.currentIndex = row.value; if (obj.value == "twisty" || tree.view.isContainer(row.value)) { this._changeOpenState(tree, row.value, !tree.view.isContainerOpen(row.value)); } else { this._openURLIn( event, tree, 'current'); } } ]]></body> </method> <method name="setPopupShowing"> <parameter name="flag"/> <body> <![CDATA[ this._popupShowing = (flag == true); ]]> </body> </method> </implementation> <handlers> <handler event="keypress" keycode="VK_ESCAPE" group="system"> if (this.parentNode.nodeName != "popup") return; try { this.parentNode.hidePopup(); } catch(e) {} </handler> <!-- Hack to prevent ctrl-b from changing the menulist. Ctrl-b is mapped to toggle sidebar --> <handler event="keypress" charcode="b" modifiers="control" phase="capturing"> event.stopPropagation(); </handler> <!-- Handles tooltip --> <handler event="popupshowing" phase="capturing"><![CDATA[ try { if ("xul:tooltip" !== event.originalTarget.nodeName) return true; var row = {}, col = {}, childElt = {}; this.bookmarksTree.treeBoxObject.getCellAt(event.clientX - event.target.boxObject.x, event.clientY - event.target.boxObject.y, row, col, childElt); if (col && col.value) { col = col.value; if ("Name" === col.id) { if (row) row = row.value; if (row >= 0 && row < this.bookmarksTreeView.rowCount) { var name = this.bookmarksTreeView.table[row].Name; this.lineWrapIntoVbox(document.getElementById("ybBookmarkTooltipLabel"), name); return true; } } else if ("note" === col.id) { if (row) row = row.value; if (row >= 0 && row < this.bookmarksTreeView.rowCount) { var desc = this.bookmarksTreeView.table[row].desc; if (desc) { this.lineWrapIntoVbox(document.getElementById("ybBookmarkTooltipLabel"), desc); return true; } } } } event.preventDefault(); } catch(e) { yDebug.print("ybSidebarOverlay.xml::handler::popupshowing::exception: "+e, YB_LOG_MESSAGE); } ]]></handler> <handler event="mousemove" phase="capturing"><![CDATA[ try { if(ybookmarksUtils.getFFMajorVersion() > 2) { var row = {}, col = {}, childElt = {}; this.bookmarksTree.treeBoxObject.getCellAt(event.clientX - event.target.boxObject.x, event.clientY - event.target.boxObject.y, row, col, childElt); if (col && col.value) { col = col.value; if ("Name" === col.id) { if (row) row = row.value; if (row >= 0 && row < this.bookmarksTreeView.rowCount) { var name = this.bookmarksTreeView.table[row].Name; this.lineWrapIntoVbox(document.getElementById("ybBookmarkTooltipLabel"), name); return true; } } else if ("note" === col.id) { if (row) row = row.value; if (row >= 0 && row < this.bookmarksTreeView.rowCount) { var desc = this.bookmarksTreeView.table[row].desc; if (desc) { this.lineWrapIntoVbox(document.getElementById("ybBookmarkTooltipLabel"), desc); return true; } } } } } event.preventDefault(); } catch(e) { yDebug.print("ybSidebarOverlay.xml::handler::popupshowing::exception: "+e, YB_LOG_MESSAGE); } ]]></handler> <handler event="click" phase="capturing"><![CDATA[ this.processClick(event); ]]></handler> </handlers> <content> <xul:stringbundle src="chrome://ybookmarks/locale/ybookmarks.properties" anonid="ybsidebar-stringbundle"/> <xul:tooltip id="ybBookmarkTooltip"> <xul:vbox id="ybBookmarkTooltipLabel" width="180px" /> </xul:tooltip> <xul:popup id="ybContextMenu" onpopupshowing="return _createContextMenu(event);" onpopuphidden ="_shouldClosePopup(false);"> <xul:menuitem label="&ybcontextmenu.openInWindow.label;" anonid="ybContextMenu-open-in-window" accesskey="&ybcontextmenu.openInWindow.accesskey;" default="true" oncommand="_openURLIn(event, document.popupNode.parentNode, 'current');"/> <xul:menuitem label="&ybcontextmenu.openInNewWindow.label;" anonid="ybContextMenu-open-in-new-window" accesskey="&ybcontextmenu.openInNewWindow.accesskey;" oncommand="_openURLIn(event, document.popupNode.parentNode, 'window');"/> <xul:menuitem label="&ybcontextmenu.openInNewTab.label;" anonid="ybContextMenu-open-in-new-tab" accesskey="&ybcontextmenu.openInNewTab.accesskey;" oncommand="_openURLIn(event, document.popupNode.parentNode, 'tab');"/> <xul:menuseparator anonid="ybContextMenu-separator1"/> <xul:menuitem label="&ybcontextmenu.newBookmark.label;" anonid="ybContextMenu-new-bookmark" accesskey="&ybcontextmenu.newBookmark.accesskey;" oncommand="_newBookmark();"/> <xul:menuseparator anonid="ybContextMenu-separator2"/> <xul:menuitem label="&ybcontextmenu.deleteBookmark.label;" anonid="ybContextMenu-delete-bookmark" accesskey="&ybcontextmenu.deleteBookmark.accesskey;" oncommand="_deleteBookmark(event, document.popupNode.parentNode);"/> <xul:menuseparator anonid="ybContextMenu-separator3"/> <xul:menuitem label="&ybcontextmenu.moreAbout.label;" anonid="ybContextMenu-about" accesskey="&ybcontextmenu.moreAbout.accesskey;" oncommand="_moreAbout(event, document.popupNode.parentNode);"/> <xul:menuitem label="&ybcontextmenu.properties.label;" anonid="ybContextMenu-properties" accesskey="&ybcontextmenu.properties.accesskey;" oncommand="_editBookmark(event, document.popupNode.parentNode);"/> <xul:menuitem label="&ybcontextmenu.openTag.label;" anonid="ybContextMenu-openTag" accesskey="&ybcontextmenu.openTag.accesskey;" oncommand="_openTag(event, document.popupNode.parentNode);"/> <xul:menuitem label="&ybcontextmenu.openContainer.label;" anonid="ybContextMenu-openContainer" accesskey="&ybcontextmenu.openContainer.accesskey;" oncommand="_openBookmarks(event, document.popupNode.parentNode);"/> </xul:popup> <xul:vbox flex="1" allowevents="true"> <xul:vbox anonid="ybsidebar-topContainer" allowevents="true"> <xul:sidebarheader align="center" anonid="ybsidebar-showSidebar" hidden="false"> <xul:label value ="&ybsidebar.title;" flex="1" crop="end"/> <xul:toolbarbutton anonid="ybsidebar-pin-button" class="yb-pin-button" tooltiptext="&ybsidebar.header.pinButttonLabel;" oncommand="togglePinState();"/> <!-- class tabs-closebutton is a FF style class --> <xul:toolbarbutton class="tabs-closebutton" tooltiptext="&ybsidebar.header.closeButtonLabel;" oncommand="ybookmarksUtils.getTopWindow().toggleSidebar('viewYBookmarksSidebar', false);"/> <!-- <xul:toolbarbutton tooltiptext="&ybsidebar.switchToSidebar.tooltip;" class="ybsidebar-showSidebarButton" oncommand="_openYBSidebar();" /> --> </xul:sidebarheader> <xul:hbox anonid="ybsidebar-searchContainer" align="center" style="padding: 0px !important;" class="ybsidebar-search"> <xul:label value="&ybsidebar.search.label;"/> <!-- <xul:image class="ybsidebar-search1" /> --> <xul:textbox anonid="ybsidebar-search-query" flex="1000" type="timed" timeout="750" class="ybsidebar-search2" oncommand="_search(this.value);" onkeyup="_onSearchKeyUp(event);" oninput="iconHandler(this.value);"/> <xul:toolbarbutton anonid="ybsidebar-search-reset" class="ybsidebar-search-reset-style" onmouseover="reseticonHandler('hover');" onmouseout="reseticonHandler('out');"/> </xul:hbox> <xul:hbox> <xul:progressmeter flex="1" mode="normal" anonid="ybsidebar-search-progress-meter" value="0" collapsed="false"/> </xul:hbox> </xul:vbox> <xul:vbox flex="1" class="ybsidebar-tree-container"> <xul:vbox flex="1"> <xul:hbox anonid="ybsidebar-tagsLabelContainer" class="ysidebar-label-container" align="center"> <xul:label value="&ybsidebar.tags.label;"/> <xul:hbox pack="end" flex="1" align="center"> <xul:spacer flex="1000" /> <xul:label anonid="ybsidebar-tags-count" id="ybsidebar-tags-count" value="(##)" /> <xul:menulist anonid="ybsidebar-tags-sort-menu" id="ybsidebar-tags-sort-menu" label="View" flex="1" sizetopopup="none"> <xul:menupopup> <xul:menuitem label="&ybsidebar.tags.by_alpha;" id="ybsidebar-tags-sort-menu-alpha" /> <xul:menuitem label="&ybsidebar.tags.by_freq;" id="ybsidebar-tags-sort-menu-freq" /> </xul:menupopup> </xul:menulist> </xul:hbox> </xul:hbox> <xul:deck anonid="ybsidebar-tags-deck" flex="1"> <xul:tree anonid="ybbookmarks-tree-tags" id="ybbookmarks-tree-tags" hidecolumnpicker="true" class="plain" seltype="single" contextmenu="ybContextMenu" flex="1"> <xul:treecols> <xul:treecol id="Name" sortActive="true" sortDirection="ascending" flex="10" primary="true" hideheader="true"/> <xul:treecol id="NumBookmarks" flex="1" hideheader="true" align="end" pack="end" hidden="false" class="ybSidebarTagNum"/> </xul:treecols> <xul:treechildren alternatingbackground="true"/> </xul:tree> <xul:vbox anonid="ybbookmarks-no-tags-results" class="ybsidebar-no-search-result-box" flex="1" collapsed="true"> <xul:deck selectedIndex="0"> <xul:vbox> <xul:text class="ybsidebar-noSearchResultsText" value="&ybsidebar.search.noTagsFound.label;" crop="end"/> <xul:spacer class="ybsidebar-spacer"/> <xul:text class="ysidebar-textlink" onclick="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode._searchWeb('delicious');" value="&ybsidebar.search.searchDelicious.label;" crop="end"/> <xul:spacer class="ybsidebar-spacer"/> <xul:text class="ysidebar-textlink" onclick="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode._searchWeb('yahoo');" value="&ybsidebar.search.searchYahoo.label;" crop="end"/> </xul:vbox> <xul:description class="ybsidebar-searchText" crop="end">&ybsidebar.search.doSearch.label;</xul:description> <xul:description class="ybsidebar-importingText" crop="end">&ybsidebar.import.importing.label;</xul:description> </xul:deck> </xul:vbox> </xul:deck> </xul:vbox> <xul:splitter anonid="ybsidebar-tree-splitter" /> <xul:vbox flex="1"> <xul:hbox anonid="ybsidebar-bookmarksLabelContainer" class="ysidebar-label-container" align="center"> <xul:label value="&ybsidebar.bookmarks.label;"/> <xul:hbox pack="end" flex="1" align="center"> <xul:spacer flex="1000" /> <xul:label anonid="ybsidebar-bookmarks-count" id="ybsidebar-bookmarks-count" value="(##)" /> <xul:menulist anonid="ybsidebar-bookmarks-sort-menu" id="ybsidebar-bookmarks-sort-menu" label="View" flex="1" sizetopopup="none"> <xul:menupopup> <xul:menuitem label="&ybsidebar.bookmarks.by_added_date;" id="ybsidebar-bookmarks-sort-menu-last-added" /> <xul:menuitem label="&ybsidebar.bookmarks.by_alpha;" id="ybsidebar-bookmarks-sort-menu-alpha" /> <xul:menuitem label="&ybsidebar.bookmarks.by_site;" id="ybsidebar-bookmarks-sort-menu-site" /> <xul:menuitem label="&ybsidebar.bookmarks.by_most_visited;" id="ybsidebar-bookmarks-sort-menu-most-visited" /> <xul:menuitem label="&ybsidebar.bookmarks.by_last_visited;" id="ybsidebar-bookmarks-sort-menu-last-visited" /> </xul:menupopup> </xul:menulist> </xul:hbox> </xul:hbox> <xul:deck anonid="ybsidebar-bookmarks-deck" flex="1"> <xul:tree anonid="ybbookmarks-tree-bookmarks" id="ybbookmarks-tree-bookmarks" hidecolumnpicker="true" class="plain" onclick="if(event.button == 0){ openItemClick(event, this); } else if (event.button == 1) { _openURLIn(event, this, 'tab'); }" onkeypress="if ((event.keyCode == KeyEvent.DOM_VK_RETURN) || (event.keyCode == KeyEvent.DOM_VK_ENTER)) {openItemOnEnter(event, this);}" seltype="single" contextmenu="ybContextMenu" flex="1"> <xul:treecols> <xul:treecol id="Name" flex="10" primary="true" hideheader="true" sortDirection="ascending" sortActive="true"/> <xul:treecol id="note" flex="1" hideheader="true" align="end" pack="end" hidden="false" class="ybSidebarNotes"/> <xul:treecol id="last_visited" flex="1" hideheader="true" hidden="true" /> <xul:treecol id="last_added" flex="1" hideheader="true" hidden="true" /> </xul:treecols> <xul:treechildren alternatingbackground="true" tooltip="ybBookmarkTooltip"/> </xul:tree> <xul:vbox anonid="ybbookmarks-no-bookmarks-results" class="ybsidebar-no-search-result-box" flex="1" collapsed="true"> <xul:deck selectedIndex="0"> <xul:vbox> <xul:label class="ybsidebar-noSearchResultsText" value="&ybsidebar.search.noBookmarksFound.label;" crop="end"/> </xul:vbox> <xul:label class="ybsidebar-searchText" crop="end"/> </xul:deck> </xul:vbox> </xul:deck> </xul:vbox> </xul:vbox> <xul:hbox anonid="ybsidebar-bottomContainer" class="ybsidebar-info-container" align="center" style="margin:0px;"> <xul:image anonid="ybsidebar-login-image" class="ybsidebar-info-image" onclick="_openHome(event);" /> <xul:spacer style="width:1em;"/> <xul:description anonid="ybsidebar-login-status" value="(user)" style="margin: 0px;" /> <xul:description anonid="ybsidebar-login-status-2" value="&ybsidebar.loginStatus.on;" style="margin: 0px;" /> <xul:description anonid="ybsidebar-login-status-3" value="&ybsidebar.provider.label;" style="margin: 0px;" flex="1" crop="end" class="ysidebar-textlink" linktype="standard" onclick="_openHome(event);" /> </xul:hbox> </xul:vbox> </content> </binding> <binding id="splitter" extends="chrome://global/content/bindings/splitter.xml#splitter"> <implementation> <constructor> <![CDATA[ this._sidebar = this.parentNode.parentNode.parentNode; this._topContainer = document.getAnonymousElementByAttribute(this._sidebar, "anonid", "ybsidebar-topContainer"); this._bottomContainer = document.getAnonymousElementByAttribute(this._sidebar, "anonid", "ybsidebar-bottomContainer"); this.tagsTree = document.getAnonymousElementByAttribute(this._sidebar, "anonid", "ybbookmarks-tree-tags"); this.bookmarksTree = document.getAnonymousElementByAttribute(this._sidebar, "anonid", "ybbookmarks-tree-bookmarks"); this._tagsLabelContainer = document.getAnonymousElementByAttribute(this._sidebar, "anonid", "ybsidebar-tagsLabelContainer"); this._bookmarksLabelContainer = document.getAnonymousElementByAttribute(this._sidebar, "anonid", "ybsidebar-bookmarksLabelContainer"); ]]> </constructor> <field name="_sidebar">null</field> <field name="_topContainer">null</field> <field name="_bottomContainer">null</field> <field name="tagsTree">null</field> <field name="bookmarksTree">null</field> <field name="_bookmarksLabelContainer">null</field> <field name="_tagsLabelContainer">null</field> </implementation> <handlers> <handler event="mousedown"><![CDATA[ this._startDragging = true; ]]></handler> <handler event="mouseup"><![CDATA[ this._startDragging = false; ]]></handler> <handler event="mousemove"><![CDATA[ //stop if mouse up if (!this._startDragging) { return; } //set this for sidebar this._sidebar.tagsLabelContainerHeight = this._tagsLabelContainer.boxObject.height; var previousElement = this.tagsTree.parentNode.parentNode; var nextElement = this.bookmarksTree.parentNode.parentNode; var topExtraHeight = this._topContainer.boxObject.height + this.boxObject.height var topTreeHeight = event.clientY - topExtraHeight; var bottomExtraHeight = this._bottomContainer.boxObject.height; var bottomTreeHeight = this._sidebar.boxObject.height - topExtraHeight - topTreeHeight - bottomExtraHeight; //stop if the height of one of the trees is smaller than min var min = 20 + this._tagsLabelContainer.boxObject.height; if ((previousElement.boxObject.height < min && event.clientY < this._topContainer.boxObject.height) || (nextElement.boxObject.height < min && event.clientY > (this._topContainer.boxObject.height + previousElement.boxObject.height + this.boxObject.height)) || topTreeHeight < min || bottomTreeHeight < min ) { return; } previousElement.setAttribute("minheight", topTreeHeight); previousElement.setAttribute("maxheight", topTreeHeight); event.preventDefault(); event.stopPropagation(); ]]></handler> </handlers> </binding> </bindings> <!-- Local Variables: mode:javascript End: -->